package ${packageName}.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.spark.common.constants.Constants;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.spark.common.annotation.DictTranslate;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.spark.common.constants.validGroup.AddGroup;
import com.spark.common.constants.validGroup.EditGroup;
import com.spark.common.core.Result;
import com.spark.common.query.QueryGenerator;
import com.spark.common.utils.TreeBuilderUtils;
import com.spark.common.utils.TreeIsLeafUtils;
import ${packageName}.entity.${ClassName};
import ${packageName}.service.I${ClassName}Service;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;

/**
 * ${functionName}Controller
 *
 * @author ${authorName}
 * @date ${dateTime}
 */
@RestController
@RequestMapping(value = "/${modulePath}/${businessPath}")
public class ${ClassName}Controller {

    @Resource
    private I${ClassName}Service ${className}Service;

    <#if model?? && model == "single">
    /**
     * 分页列表查询
     *
     * @param ${className} ${functionName}对象
     * @param pageNo   分页
     * @param pageSize 分页
     * @return ${functionName}列表
     */
    @DictTranslate
    @PreAuthorize("@sp.hasPerm('${prem}:query')")
    @GetMapping(value = "/queryPageList")
    public Result<?> queryPageList(${ClassName} ${className},
                                   @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
                                   @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize) {
        QueryWrapper<${ClassName}> queryWrapper = QueryGenerator.initQueryWrapper(${className});
        Page<${ClassName}> page = new Page<${ClassName}>(pageNo, pageSize);
        IPage<${ClassName}> pageList = ${className}Service.page(page, queryWrapper);
        return Result.ok(pageList);
    }

    /**
     * 列表查询
     *
     * @param ${className} ${functionName}对象
     * @return ${functionName}列表
     */
    @DictTranslate
    @PreAuthorize("@sp.hasPerm('${prem}:query')")
    @GetMapping(value = "/queryList")
    public Result<?> queryList(${ClassName} ${className}) {
        QueryWrapper<${ClassName}> queryWrapper = QueryGenerator.initQueryWrapper(${className});
        List<${ClassName}> list = ${className}Service.list(queryWrapper);
        return Result.ok(list);
    }
    <#else >
    /**
     * 懒加载列表查询
     * : 如果pid为空则查询所有父级,反之查询子级数据
     *
     * @param ${className} ${functionName}对象
     * @return ${functionName}列表
     */
    @DictTranslate
    @PreAuthorize("@sp.hasPerm('${prem}:query')")
    @GetMapping(value = "/queryLazyList")
    public Result<?> queryLazyList(${ClassName} ${className}) {
        QueryWrapper<${ClassName}> queryWrapper = QueryGenerator.initQueryWrapper(${className});
        if (StringUtils.isEmpty(${className}.getPid())) {
            ${className}.setPid("0");
        }
        List<${ClassName}> list = ${className}Service.list(queryWrapper);
        return Result.ok(list);
    }

    /**
     * 列表查询
     *  :结果支持两种结构。1.平级('flat') 2.层级('layer')
     *  :需要再请求头中传入key为: model= 'flat' | 'layer'，默认 'layer'
     *
     * @param ${className} ${functionName}对象
     * @return ${functionName}列表: 结果支持两种结构。1.平级('flat') 2.层级('layer')
     */
    @DictTranslate
    @PreAuthorize("@sp.hasPerm('${prem}:query')")
    @GetMapping(value = "/queryList")
    public Result<?> queryList(${ClassName} ${className}, HttpServletRequest request) {
        String model = request.getHeader(Constants.TREE_MODEL_KEY);
        model = StringUtils.isEmpty(model) ? "layer" : model;
        QueryWrapper<${ClassName}> queryWrapper = QueryGenerator.initQueryWrapper(${className});
        List<${ClassName}> list = ${className}Service.list(queryWrapper);
        if ("layer".equals(model)){
            // 结构化为层级数据: 这里需要指定id,pid,children字段,此处为默认
            TreeBuilderUtils builder = new TreeBuilderUtils();
            // 结构化时设置叶子节点
            List<${ClassName}> buildTree = builder.buildTree(list, true);
            // 可以按照某个属性进行排序
            // builder.sortTreeNodes(buildTree,"{排序实体字段}",true);
            return Result.ok(buildTree);
        }
        return Result.ok(list);
    }
    </#if>

    /**
     * 通过ID查询
     *
     * @param id 主键
     * @return ${functionName}对象
     */
    @DictTranslate
    @PreAuthorize("@sp.hasPerm('${prem}:queryById')")
    @GetMapping(value = "/queryById")
    public Result<?> queryById(@RequestParam String id) {
        ${ClassName} ${className} = ${className}Service.getById(id);
        if (Objects.isNull(${className})) {
            return Result.fail("数据获取失败");
        }
        return Result.ok(${className});
    }

    /**
     * 新增
     *
     * @param ${className} ${functionName}对象
     * @return 成功或失败
     */
    @PreAuthorize("@sp.hasPerm('${prem}:add')")
    @PostMapping(value = "/add")
    public Result<?> add(@Validated(AddGroup.class) @RequestBody ${ClassName} ${className}) {
        <#if model?? && model == "tree">
        // 设置数据叶子节点：需要指定父级ID(pid)和叶子节点(isLeaf)字段名称，此处为默认
        TreeIsLeafUtils<${ClassName}> isLeafUtils = new TreeIsLeafUtils<>(${className}Service);
        isLeafUtils.dealIsLeaf(${className}, "add", null);
        </#if>
        boolean save = ${className}Service.save(${className});
        return Result.flag(save);
    }

    /**
     * 编辑
     *
     * @param ${className} ${functionName}对象
     * @return 成功或失败
     */
    @PreAuthorize("@sp.hasPerm('${prem}:edit')")
    @PostMapping(value = "/edit")
    public Result<?> edit(@Validated(EditGroup.class) @RequestBody ${ClassName} ${className}) {
        <#if model?? && model == "tree">
        // 设置数据叶子节点：需要指定父级ID(pid)和叶子节点(isLeaf)字段名称，此处为默认
        TreeIsLeafUtils<${ClassName}> isLeafUtils = new TreeIsLeafUtils<>(${className}Service);
        isLeafUtils.dealIsLeaf(${className}, "edit", null);
        </#if>
        boolean update = ${className}Service.updateById(${className});
        return Result.flag(update);
    }

    /**
     * 通过id删除
     *
     * @param id 主键
     * @return 成功或失败
     */
    @PreAuthorize("@sp.hasPerm('${prem}:del')")
    @DeleteMapping(value = "/delete/{id}")
    public Result<?> delete(@PathVariable(name = "id") String id) {
        <#if model?? && model == "tree">
        // 设置数据叶子节点：需要指定父级ID(pid)和叶子节点(isLeaf)字段名称，此处为默认
        TreeIsLeafUtils<${ClassName}> isLeafUtils = new TreeIsLeafUtils<>(${className}Service);
        isLeafUtils.dealIsLeaf(null, "del", id);
        </#if>
        boolean update = ${className}Service.removeById(id);
        return Result.flag(update);
    }

<#if model?? && model == "single">
    /**
     * 通过id批量删除删除
     *
     * @param ids 主键
     * @return 成功或失败
     */
    @PreAuthorize("@sp.hasPerm('${prem}:batchDel')")
    @DeleteMapping(value = "/deleteBatchByIds/{ids}")
    public Result<?> deleteBatchByIds(@PathVariable(name = "ids") String[] ids) {
        boolean update = ${className}Service.removeBatchByIds(Arrays.asList(ids));
        return Result.flag(update);
    }
</#if>

}
